using SqlSugar;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Repository.sugar;

namespace Model.Utils
{
    /// <summary>
    /// 实体生成工具类
    /// 用于自动生成数据库表对应的实体类
    /// </summary>
    public class EntityGenerator
    {
        /// <summary>
        /// 生成指定表的实体类
        /// </summary>
        /// <param name="tableNames">要生成实体的表名数组</param>
        /// <param name="namespaceName">命名空间名称</param>
        /// <param name="outputPath">输出路径，如果为空则使用Model项目路径</param>
        /// <returns>生成结果</returns>
        public static EntityGenerationResult GenerateEntities(string[] tableNames, string namespaceName = "Model", string outputPath = null)
        {
            try
            {
                // 初始化数据库连接
                DbContext.Init(BaseDBConfig.ConnectionString, SqlSugar.DbType.MySql);

                // 获取数据库上下文
                var dbContext = DbContext.Context;

                // 设置输出路径
                if (string.IsNullOrEmpty(outputPath))
                {
                    outputPath = GetModelProjectPath();
                }

                // 确保目录存在
                if (!Directory.Exists(outputPath))
                {
                    Directory.CreateDirectory(outputPath);
                }

                // 过滤掉可能有问题的表
                var filteredTableNames = FilterProblematicTables(tableNames);

                if (filteredTableNames.Length == 0)
                {
                    return new EntityGenerationResult
                    {
                        Success = false,
                        Message = "没有可生成的表（所有表都被过滤掉了）",
                        FilteredTables = tableNames.Except(filteredTableNames).ToArray()
                    };
                }

                // 生成实体类
                dbContext.CreateClassFileByDBTalbe(
                    outputPath,           // 实体类存放路径
                    namespaceName,        // 命名空间
                    filteredTableNames,   // 过滤后的表名
                    "",                   // 实现接口（可选）
                    false                 // 是否序列化
                );

                // 获取生成的文件列表
                var generatedFiles = GetGeneratedFiles(outputPath, filteredTableNames);

                return new EntityGenerationResult
                {
                    Success = true,
                    Message = $"成功生成 {filteredTableNames.Length} 个表的实体类",
                    OutputPath = outputPath,
                    GeneratedFiles = generatedFiles,
                    TableNames = filteredTableNames,
                    FilteredTables = tableNames.Except(filteredTableNames).ToArray()
                };
            }
            catch (Exception ex)
            {
                return new EntityGenerationResult
                {
                    Success = false,
                    Message = "生成实体失败",
                    Error = ex.Message,
                    StackTrace = ex.StackTrace
                };
            }
        }

        /// <summary>
        /// 生成所有表的实体类（排除有问题的表）
        /// </summary>
        /// <param name="namespaceName">命名空间名称</param>
        /// <param name="outputPath">输出路径</param>
        /// <returns>生成结果</returns>
        public static EntityGenerationResult GenerateAllEntities(string namespaceName = "Model", string outputPath = null)
        {
            try
            {
                // 初始化数据库连接
                DbContext.Init(BaseDBConfig.ConnectionString, SqlSugar.DbType.MySql);

                // 获取数据库上下文
                var dbContext = DbContext.Context;

                // 设置输出路径
                if (string.IsNullOrEmpty(outputPath))
                {
                    outputPath = GetModelProjectPath();
                }

                // 确保目录存在
                if (!Directory.Exists(outputPath))
                {
                    Directory.CreateDirectory(outputPath);
                }

                // 获取所有表名
                var allTableNames = GetAllTableNames();

                // 过滤掉可能有问题的表
                var filteredTableNames = FilterProblematicTables(allTableNames.ToArray());

                if (filteredTableNames.Length == 0)
                {
                    return new EntityGenerationResult
                    {
                        Success = false,
                        Message = "没有可生成的表（所有表都被过滤掉了）",
                        FilteredTables = allTableNames.ToArray()
                    };
                }

                // 生成实体类
                dbContext.CreateClassFileByDBTalbe(
                    outputPath,           // 实体类存放路径
                    namespaceName,        // 命名空间
                    filteredTableNames,   // 过滤后的表名
                    "",                   // 实现接口（可选）
                    false                 // 是否序列化
                );

                // 获取生成的文件列表
                var generatedFiles = Directory.GetFiles(outputPath, "*.cs").Select(Path.GetFileName).ToArray();

                return new EntityGenerationResult
                {
                    Success = true,
                    Message = $"成功生成 {filteredTableNames.Length} 个表的实体类",
                    OutputPath = outputPath,
                    GeneratedFiles = generatedFiles,
                    TableNames = filteredTableNames,
                    FilteredTables = allTableNames.Except(filteredTableNames).ToArray()
                };
            }
            catch (Exception ex)
            {
                return new EntityGenerationResult
                {
                    Success = false,
                    Message = "生成实体失败",
                    Error = ex.Message,
                    StackTrace = ex.StackTrace
                };
            }
        }

        /// <summary>
        /// 安全生成指定表的实体类（逐个生成，避免内存问题）
        /// </summary>
        /// <param name="tableNames">要生成实体的表名数组</param>
        /// <param name="namespaceName">命名空间名称</param>
        /// <param name="outputPath">输出路径</param>
        /// <returns>生成结果</returns>
        public static EntityGenerationResult GenerateEntitiesSafely(string[] tableNames, string namespaceName = "Model", string outputPath = null)
        {
            var results = new List<EntityGenerationResult>();
            var successTables = new List<string>();
            var failedTables = new List<string>();

            try
            {
                // 初始化数据库连接
                DbContext.Init(BaseDBConfig.ConnectionString, SqlSugar.DbType.MySql);

                // 设置输出路径
                if (string.IsNullOrEmpty(outputPath))
                {
                    outputPath = GetModelProjectPath();
                }

                // 确保目录存在
                if (!Directory.Exists(outputPath))
                {
                    Directory.CreateDirectory(outputPath);
                }

                // 逐个生成每个表的实体
                foreach (var tableName in tableNames)
                {
                    try
                    {
                        var dbContext = DbContext.Context;

                        // 生成单个表的实体类
                        dbContext.CreateClassFileByDBTalbe(
                            outputPath,           // 实体类存放路径
                            namespaceName,        // 命名空间
                            new[] { tableName },  // 单个表名
                            "",                   // 实现接口（可选）
                            false                 // 是否序列化
                        );

                        successTables.Add(tableName);

                        // 强制垃圾回收，释放内存
                        GC.Collect();
                        GC.WaitForPendingFinalizers();
                    }
                    catch (Exception ex)
                    {
                        failedTables.Add(tableName);
                        results.Add(new EntityGenerationResult
                        {
                            Success = false,
                            Message = $"生成表 {tableName} 失败",
                            Error = ex.Message,
                            TableNames = new[] { tableName }
                        });
                    }
                }

                // 获取生成的文件列表
                var generatedFiles = GetGeneratedFiles(outputPath, successTables.ToArray());

                return new EntityGenerationResult
                {
                    Success = successTables.Count > 0,
                    Message = $"成功生成 {successTables.Count} 个表，失败 {failedTables.Count} 个表",
                    OutputPath = outputPath,
                    GeneratedFiles = generatedFiles,
                    TableNames = successTables.ToArray(),
                    FailedTables = failedTables.ToArray(),
                    DetailedResults = results.ToArray()
                };
            }
            catch (Exception ex)
            {
                return new EntityGenerationResult
                {
                    Success = false,
                    Message = "安全生成实体失败",
                    Error = ex.Message,
                    StackTrace = ex.StackTrace
                };
            }
        }

        /// <summary>
        /// 获取数据库中的所有表名
        /// </summary>
        /// <returns>表名列表</returns>
        public static List<string> GetAllTableNames()
        {
            try
            {
                // 初始化数据库连接
                DbContext.Init(BaseDBConfig.ConnectionString, SqlSugar.DbType.MySql);

                // 获取数据库上下文
                var dbContext = DbContext.Context;

                // 获取所有表名
                var tableNames = dbContext.Db.DbMaintenance.GetTableInfoList()
                    .Select(t => t.Name)
                    .ToList();

                return tableNames;
            }
            catch (Exception ex)
            {
                throw new Exception($"获取表名失败: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 测试数据库连接
        /// </summary>
        /// <returns>连接测试结果</returns>
        public static ConnectionTestResult TestConnection()
        {
            try
            {
                // 初始化数据库连接
                DbContext.Init(BaseDBConfig.ConnectionString, SqlSugar.DbType.MySql);

                // 获取数据库上下文
                var dbContext = DbContext.Context;

                // 测试连接
                var result = dbContext.Db.Ado.GetDataTable("SELECT 1 as Test");

                return new ConnectionTestResult
                {
                    Success = true,
                    Message = "数据库连接成功",
                    ConnectionString = BaseDBConfig.ConnectionString,
                    TestResult = result.Rows.Count > 0 ? "连接正常" : "连接异常"
                };
            }
            catch (Exception ex)
            {
                return new ConnectionTestResult
                {
                    Success = false,
                    Message = "数据库连接失败",
                    Error = ex.Message,
                    ConnectionString = BaseDBConfig.ConnectionString
                };
            }
        }

        /// <summary>
        /// 过滤掉可能有问题的表
        /// </summary>
        /// <param name="tableNames">表名数组</param>
        /// <returns>过滤后的表名数组</returns>
        private static string[] FilterProblematicTables(string[] tableNames)
        {
            // 定义可能有问题的表名模式
            var problematicPatterns = new[]
            {
                "lend",           // 可能导致内存溢出的表
                "log",            // 日志表通常数据量大
                "record",         // 记录表可能数据量大
                "history",        // 历史表可能数据量大
                "temp",           // 临时表
                "backup",         // 备份表
                "cache"           // 缓存表
            };

            var filteredTables = tableNames.Where(tableName =>
            {
                var lowerTableName = tableName.ToLower();

                // 检查是否包含问题模式
                foreach (var pattern in problematicPatterns)
                {
                    if (lowerTableName.Contains(pattern))
                    {
                        return false; // 过滤掉
                    }
                }

                return true; // 保留
            }).ToArray();

            return filteredTables;
        }

        /// <summary>
        /// 获取Model项目路径
        /// </summary>
        /// <returns>Model项目路径</returns>
        private static string GetModelProjectPath()
        {
            // 获取当前程序集所在目录
            var currentDirectory = AppDomain.CurrentDomain.BaseDirectory;

            // 查找Model项目目录
            var modelPath = Path.Combine(currentDirectory, "..", "..", "..", "Model");

            // 如果找不到，尝试其他可能的路径
            if (!Directory.Exists(modelPath))
            {
                modelPath = Path.Combine(currentDirectory, "Model");
            }

            if (!Directory.Exists(modelPath))
            {
                // 如果还是找不到，使用当前目录下的Model文件夹
                modelPath = Path.Combine(currentDirectory, "Model");
                Directory.CreateDirectory(modelPath);
            }

            return modelPath;
        }

        /// <summary>
        /// 获取生成的文件列表
        /// </summary>
        /// <param name="outputPath">输出路径</param>
        /// <param name="tableNames">表名数组</param>
        /// <returns>生成的文件名数组</returns>
        private static string[] GetGeneratedFiles(string outputPath, string[] tableNames)
        {
            var files = new List<string>();

            foreach (var tableName in tableNames)
            {
                // 将表名转换为类名（首字母大写，下划线转驼峰）
                var className = ConvertTableNameToClassName(tableName);
                var fileName = $"{className}.cs";
                var filePath = Path.Combine(outputPath, fileName);

                if (File.Exists(filePath))
                {
                    files.Add(fileName);
                }
            }

            return files.ToArray();
        }

        /// <summary>
        /// 将表名转换为类名
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <returns>类名</returns>
        private static string ConvertTableNameToClassName(string tableName)
        {
            if (string.IsNullOrEmpty(tableName))
                return string.Empty;

            // 移除表名前缀（如果有的话）
            var name = tableName;
            if (name.StartsWith("t_") || name.StartsWith("tb_"))
            {
                name = name.Substring(2);
            }

            // 将下划线分隔的单词转换为PascalCase
            var parts = name.Split('_');
            var className = string.Join("", parts.Select(part =>
                char.ToUpper(part[0]) + part.Substring(1).ToLower()));

            return className;
        }
    }

    /// <summary>
    /// 实体生成结果
    /// </summary>
    public class EntityGenerationResult
    {
        /// <summary>
        /// 是否成功
        /// </summary>
        public bool Success { get; set; }

        /// <summary>
        /// 消息
        /// </summary>
        public string Message { get; set; }

        /// <summary>
        /// 错误信息
        /// </summary>
        public string Error { get; set; }

        /// <summary>
        /// 堆栈跟踪
        /// </summary>
        public string StackTrace { get; set; }

        /// <summary>
        /// 输出路径
        /// </summary>
        public string OutputPath { get; set; }

        /// <summary>
        /// 生成的文件列表
        /// </summary>
        public string[] GeneratedFiles { get; set; }

        /// <summary>
        /// 表名列表
        /// </summary>
        public string[] TableNames { get; set; }

        /// <summary>
        /// 被过滤掉的表名列表
        /// </summary>
        public string[] FilteredTables { get; set; }

        /// <summary>
        /// 失败的表名列表
        /// </summary>
        public string[] FailedTables { get; set; }

        /// <summary>
        /// 详细结果列表
        /// </summary>
        public EntityGenerationResult[] DetailedResults { get; set; }
    }

    /// <summary>
    /// 连接测试结果
    /// </summary>
    public class ConnectionTestResult
    {
        /// <summary>
        /// 是否成功
        /// </summary>
        public bool Success { get; set; }

        /// <summary>
        /// 消息
        /// </summary>
        public string Message { get; set; }

        /// <summary>
        /// 错误信息
        /// </summary>
        public string Error { get; set; }

        /// <summary>
        /// 连接字符串
        /// </summary>
        public string ConnectionString { get; set; }

        /// <summary>
        /// 测试结果
        /// </summary>
        public string TestResult { get; set; }
    }
}